﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Windows.Forms;
using Microsoft.WindowsServerSolutions.Administration.ObjectModel;
using Microsoft.WindowsServerSolutions.Administration.ObjectModel.ComponentServices;
using TV4Home.Server.TVEInteractionLibrary.Interfaces;
using TV4Home.Server.Vail.AddIn.TVChannels;

namespace TV4Home.Server.Vail.AddIn
{
    public class TVChannelsSubTabPage : Page
    {
        public TVChannelsSubTabPage()
            : base(new Guid("49AD78B4-4014-4028-A905-62F87EE5FE88"),
            "TV Channels",
            "View TV channels.")
        {
        }

        protected override PageContent CreateContent()
        {
            return PageContent.Create<WebChannelDetailed>(
               new SubTabListProvider(this),
               SubTabListColumns.CreateColumns(),
               SubTabListGroupings.CreateGroupings(),
               SubTabTasks.CreateTasks(),
               SubTabDetails.GetDetails
            );
        }
    }

    namespace TVChannels
    {
        public class SubTabListProvider : ListProvider<WebChannelDetailed>
        {
            public static ITVEInteraction wcfChannel = null;

            public SubTabListProvider(IServiceProvider serviceProvider)
            {
                SubTabTasks.serviceProvider = serviceProvider;
            }

            protected override void RefreshAndListenForUpdates(IList<WebChannelDetailed> list)
            {
                try
                {
                    this.Errors.Reset();

                    if (wcfChannel == null)
                        wcfChannel = ChannelFactory<ITVEInteraction>.CreateChannel(new NetNamedPipeBinding() { MaxReceivedMessageSize = 10000000 }, new EndpointAddress("net.pipe://localhost/TV4Home.Server.CoreService/TVEInteractionService"));

                    if (SubTabTasks.SelectedChannelGroupId == 0)
                    {
                        WebChannelGroup firstGroup = wcfChannel.GetGroups().FirstOrDefault();
                        if (firstGroup == null)
                            return;

                        SubTabTasks.SelectedChannelGroupId = firstGroup.IdGroup;
                    }

                    foreach (WebChannelDetailed tvChannel in wcfChannel.GetChannelsDetailed(SubTabTasks.SelectedChannelGroupId))
                    {
                        list.Add(tvChannel);
                    }
                }
                catch (Exception ex)
                {
                    this.Errors.Report(new ErrorInfo("Couldn't retrieve data.", ex));

                    if (ex.InnerException != null)
                        this.Errors.Report(new ErrorInfo("InnerException", ex.InnerException));

                    wcfChannel = null;
                }
            }

            protected override void StopListeningForUpdates()
            {

            }

            protected override string GetObjectDisplayName(WebChannelDetailed businessObj)
            {
                return businessObj.DisplayName;
            }

            protected override string GetObjectId(WebChannelDetailed businessObj)
            {
                return businessObj.IdChannel.ToString();
            }

            protected override System.Drawing.Icon GetObjectIcon(WebChannelDetailed businessObj)
            {
                return businessObj.FreeToAir == 1 ? Properties.Resources.TV_fta : Properties.Resources.TV_scrambled;
            }
        }

        static class SubTabListColumns
        {
            public static ListColumnCollection<WebChannelDetailed> CreateColumns()
            {
                return new ListColumnCollection<WebChannelDetailed>()
                           {
                               new ListColumn<WebChannelDetailed>("Name", x => x.DisplayName)
                                   {
                                       IconProvider = x =>
                                                          {
                                                              if (x.IsTv)
                                                                  return x.FreeToAir == 1 ? Properties.Resources.TV_fta : Properties.Resources.TV_scrambled;
                                                              else
                                                                  return x.FreeToAir == 1 ? Properties.Resources.Radio_fta : Properties.Resources.Radio_scrambled;
                                                          },
                                       IsRequired = true
                                   },
                               new ListColumn<WebChannelDetailed>("Grab EPG", x => x.GrabEpg.ToString()),
                               new ListColumn<WebChannelDetailed>("Last Grab Time", x => x.LastGrabTime != SubTabDetails.DateTimeMin ? x.LastGrabTime.ToString() : "")
                           };
            }
        }

        static class SubTabListGroupings
        {
            public static ListGroupingCollection<WebChannelDetailed> CreateGroupings()
            {
                ListGroupingCollection<WebChannelDetailed> groupCollection =
                    new ListGroupingCollection<WebChannelDetailed>
                        {
                            new ListGrouping<WebChannelDetailed>("Free To Air / Scrambled", x => x.FreeToAir == 1 ? new ListGroup<WebChannelDetailed>("Free To Air") : new ListGroup<WebChannelDetailed>("Scrambled")),
                            new ListGrouping<WebChannelDetailed>("TV / Radio", x => x.IsTv ? new ListGroup<WebChannelDetailed>("TV") : new ListGroup<WebChannelDetailed>("Radio")),
                            new ListGrouping<WebChannelDetailed>("Grab EPG / Don't grab EPG", x => x.GrabEpg ? new ListGroup<WebChannelDetailed>("Grab EPG") : new ListGroup<WebChannelDetailed>("Don't grab EPG"))
                        };

                groupCollection.DefaultGrouping = groupCollection.First<ListGrouping<WebChannelDetailed>>();

                return groupCollection;
            }
        }

        static class SubTabTasks
        {
            public static int SelectedChannelGroupId { get; set; }
            public static IServiceProvider serviceProvider;

            public static TaskCollection CreateTasks()
            {
                return new TaskCollection
                           {
                               SetChannelGroupFilterTask(), 
                               RefreshTask()
                           };
            }

            private static AsyncUiTask RefreshTask()
            {
                return new AsyncUiTask("Refresh", sender =>
                {
                    DoRefresh();
                    return null;
                });
            }

            private static AsyncUiTask SetChannelGroupFilterTask()
            {
                return new AsyncUiTask("Select TV channel group to show", sender =>
                {
                    using (var form = new SelectTVChannelGroupForm())
                    {
                        form.PopulateGroups(SubTabListProvider.wcfChannel.GetGroups(), SelectedChannelGroupId);

                        if (form.ShowDialog() == DialogResult.OK)
                        {
                            SelectedChannelGroupId = form.SelectedGroupId;
                            DoRefresh();
                        }
                    }

                    return null;
                });
            }

            private static void DoRefresh()
            {
                if (serviceProvider == null)
                    return;

                DataRefresher service = serviceProvider.GetService(typeof(DataRefresher)) as DataRefresher;

                if (service != null)
                    service.Refresh();
            }
        }

        static class SubTabDetails
        {
            public static DateTime DateTimeMin = new DateTime(2000, 1, 1);

            public static DetailColumnCollection GetDetails(WebChannelDetailed businessObj)
            {
                DetailColumnCollection columns = new DetailColumnCollection();
                DetailColumn column = new DetailColumn();

                DetailGroup group = null;

                group = new DetailGroup("Channel Information")
                            {
                                {"Channel Name", businessObj.DisplayName},
                                {"Free To Air", (businessObj.FreeToAir == 1).ToString()},
                                {"Group Names", businessObj.GroupNames != null ? String.Join<string>(", ", businessObj.GroupNames) : ""},
                                {"Current Program", businessObj.CurrentProgram != null ? String.Format("{0} - {1}: {2}", businessObj.CurrentProgram.StartTime.ToShortTimeString(), businessObj.CurrentProgram.EndTime.ToShortTimeString(), businessObj.CurrentProgram.Title) : "n/a"},
                                {"Next Program", businessObj.NextProgram != null ? String.Format("{0} - {1}: {2}", businessObj.NextProgram.StartTime.ToShortTimeString(), businessObj.NextProgram.EndTime.ToShortTimeString(), businessObj.NextProgram.Title) : "n/a"},
                                {"Grab EPG", businessObj.GrabEpg.ToString()},
                                {"Last Grab Time", businessObj.LastGrabTime != DateTimeMin ? businessObj.LastGrabTime.ToString() : ""},
                                {"Times Watched", businessObj.TimesWatched.ToString()},
                                {"Total Time Watched", businessObj.TotalTimeWatched != DateTimeMin ? businessObj.TotalTimeWatched.ToString() : ""},
                                {"Visible In Guide", businessObj.VisibleInGuide.ToString()}
                            };

                column.Add(group);
                columns.Add(column);

                return columns;
            }
        }
    }
}